#include <QtGui>
#include <QtXml>

#include "JDomItem.h"
#include "JDomModel.h"

JDomModel::JDomModel(QDomDocument document, QObject *parent)
    : QAbstractItemModel(parent), domDocument(document)
{
    rootItem = new JDomItem(domDocument, 0);
}

JDomModel::~JDomModel()
{
    delete rootItem;
}

int JDomModel::columnCount(const QModelIndex &/*parent*/) const
{
    //return rootItem->columnCount();
	return 2;
}

QVariant JDomModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    if (role != Qt::DisplayRole)
        return QVariant();

    JDomItem *item = static_cast<JDomItem*>(index.internalPointer());

    QDomNode node = item->node();

    QStringList attributes;
    QDomNamedNodeMap attributeMap = node.attributes();

    switch (index.column()) {
        case 0:
            return node.nodeName();
        case 1:
            for (int i = 0; i < attributeMap.count(); ++i) {
                QDomNode attribute = attributeMap.item(i);
                attributes << attribute.nodeName() + "=\""
                              +attribute.nodeValue() + "\"";
            }
            return attributes.join(" ");
        case 2:
            return node.nodeValue().split("\n").join(" ");
        default:
            return QVariant();
    }
}

Qt::ItemFlags JDomModel::flags(const QModelIndex &index) const
{
    if (!index.isValid())
        return 0;

    return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}

QVariant JDomModel::headerData(int section, Qt::Orientation orientation,
                              int role) const
{
    if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
		//return rootItem->data(section);
        switch (section) {
            case 0:
                return tr("File");
            case 1:
                return tr("Location");
            /*case 2:
                return tr("Value");*/
            default:
                return QVariant();
        }
    }

    return QVariant();
}

QModelIndex JDomModel::index(int row, int column, const QModelIndex &parent)
            const
{
    if (!hasIndex(row, column, parent))
        return QModelIndex();

    JDomItem *parentItem;

    if (!parent.isValid())
        parentItem = rootItem;
    else
        parentItem = static_cast<JDomItem*>(parent.internalPointer());

    JDomItem *childItem = parentItem->child(row);
    if (childItem)
        return createIndex(row, column, childItem);
    else
        return QModelIndex();
}

QModelIndex JDomModel::parent(const QModelIndex &child) const
{
    if (!child.isValid())
        return QModelIndex();

    JDomItem *childItem = static_cast<JDomItem*>(child.internalPointer());
    JDomItem *parentItem = childItem->parent();

    if (!parentItem || parentItem == rootItem)
        return QModelIndex();

    return createIndex(parentItem->row(), 0, parentItem);
}

int JDomModel::rowCount(const QModelIndex &parent) const
{
    if (parent.column() > 0)
        return 0;

    JDomItem *parentItem;

    if (!parent.isValid())
        parentItem = rootItem;
    else
        parentItem = static_cast<JDomItem*>(parent.internalPointer());

    return parentItem->node().childNodes().count();
}

bool JDomModel::insertRows( int position, int rows, const QModelIndex &parent /*= QModelIndex()*/ )
{
	JDomItem *parentItem = getItem(parent);
	bool success;

	beginInsertRows(parent, position, position + rows - 1);
	success = parentItem->insertChildren(position, rows, 2/*rootItem->columnCount()*/);
	endInsertRows();

	return success;
}

bool JDomModel::removeRows( int position, int rows, const QModelIndex &parent /*= QModelIndex()*/ )
{
	JDomItem *parentItem = getItem(parent);
	bool success = true;

	beginRemoveRows(parent, position, position + rows - 1);
	success = parentItem->removeChildren(position, rows);
	endRemoveRows();

	return success;
}

bool JDomModel::setData( const QModelIndex &index, const QVariant &value, int role /*= Qt::EditRole*/ )
{
	if (role != Qt::EditRole)
		return false;

	JDomItem *item = getItem(index);
	bool result = item->setData(index.column(), value);

	if (result)
		emit dataChanged(index, index);

	return result;
}

JDomItem * JDomModel::getItem( const QModelIndex &index ) const
{
	if (index.isValid()) {
		JDomItem *item = static_cast<JDomItem*>(index.internalPointer());
		if (item) return item;
	}
	return rootItem;
}

void JDomModel::setupModelData( const QStringList &lines, JDomItem *parent )
{

}